/**********************************************************
 * HibernateUtil.java.java 
 *
 * Created by Ankur
 * Last modified Date: Aug 25, 2008 3:20:19 PM by ankur
 * Revision: <svn revision #> 
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 **********************************************************/

package com.printeverywhere.util;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * The Class HibernateUtil.
 */
public class HibernateUtil {
	
	/** Logger for this class. */
	private static final Logger logger = Logger.getLogger(HibernateUtil.class);

    /** The CONFI g_ fil e_ location. */
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml".intern();
	
	/** The Constant threadLocal. */
	private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    
    /** The configuration. */
    private  static Configuration configuration = new Configuration();    
    
    /** The session factory. */
    private static org.hibernate.SessionFactory sessionFactory;
    
    /** The config file. */
    private static String configFile = CONFIG_FILE_LOCATION;

	static {
    	try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			System.err
					.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
    }
    
    /**
     * Instantiates a new hibernate util.
     */
    private HibernateUtil() {
    }
	
	/**
	 * Gets the session.
	 * 
	 * @return the session
	 * 
	 * @throws HibernateException the hibernate exception
	 */
    public static Session getSession() throws HibernateException {
		if (logger.isDebugEnabled()) {
			logger.debug("getSession() - start"); //$NON-NLS-1$
		}

        Session session = (Session) threadLocal.get();

		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				rebuildSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("getSession() - end"); //$NON-NLS-1$
		}
        return session;
    }

	/**
	 * Rebuild session factory.
	 */
	public static void rebuildSessionFactory() {
		if (logger.isDebugEnabled()) {
			logger.debug("rebuildSessionFactory() - start"); //$NON-NLS-1$
		}

		try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			logger.error("rebuildSessionFactory()", e); //$NON-NLS-1$

			System.err
					.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}

		if (logger.isDebugEnabled()) {
			logger.debug("rebuildSessionFactory() - end"); //$NON-NLS-1$
		}
	}

	/**
	 * Close session.
	 * 
	 * @throws HibernateException the hibernate exception
	 */
    public static void closeSession() throws HibernateException {
		if (logger.isDebugEnabled()) {
			logger.debug("closeSession() - start"); //$NON-NLS-1$
		}

        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }

		if (logger.isDebugEnabled()) {
			logger.debug("closeSession() - end"); //$NON-NLS-1$
		}
    }

	/**
	 * Gets the session factory.
	 * 
	 * @return the session factory
	 */
	public static org.hibernate.SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
	 * Sets the config file.
	 * 
	 * @param configFile the new config file
	 */
	public static void setConfigFile(String configFile) {
		if (logger.isDebugEnabled()) {
			logger.debug("setConfigFile(String) - start"); //$NON-NLS-1$
		}

		HibernateUtil.configFile = configFile;
		sessionFactory = null;

		if (logger.isDebugEnabled()) {
			logger.debug("setConfigFile(String) - end"); //$NON-NLS-1$
		}
	}

	/**
	 * Gets the configuration.
	 * 
	 * @return the configuration
	 */
	public static Configuration getConfiguration() {
		return configuration;
	}
}